/*---------------------------------------------------------------------------
//
//	Copyright(C) SMIT Corporation, 2000-2010.
//
//  File	:	phyhdrv.c
//	Purpose	:	Phycical High Level Driver
//	History :
//				2006-08-18 created by pmy.
//
---------------------------------------------------------------------------*/
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "sm_trace.h"
#include "sm_kapi.h"
#include "xmsg.h"
#include "itc.h"
#include "phydrv.h"
#include "physical.h"

static drv_slot_t		s_hdrv_tab_slot[MAXSLOTID];		// slot informations table
static short			s_drvNextIndex;					// index of next polled slot
static unsigned char*	s_drv_databuf;					// intermediate buffer for read/send collision
static unsigned char	s_drv_cardIn = 1;

extern int	g_isCrudeRS;

static unsigned char camInserted;
//static int s_usbId;
static sm_sem_t s_semPhy;


void PHYS_CamDetectCallback(unsigned char status)
{
	SM_ObtainSem(&s_semPhy, -1);
	s_drv_cardIn = status;
	SM_TRACE_CRITICAL(TRMOD_PHY, "PHYS_CamDetectCallback() - status is %d\r\n", status);
	SM_ReleaseSem(&s_semPhy);
}

unsigned char PHYS_Detect(int drvslotIndex)
{
	unsigned char status;

	SM_ObtainSem(&s_semPhy, -1);
	status = s_drv_cardIn;
	SM_ReleaseSem(&s_semPhy);
	
	if (status == 0)
	{
		SM_TRACE_CRITICAL(TRMOD_PHY, "PHYS_Detect() - card out\r\n");
		return ERR_SEACH;
	}
	else
	{
		SM_TRACE_INFO(TRMOD_PHY, "PHYS_Detect() - card in\r\n");
	}

	return OK;
}


static unsigned char PHYS_RecvData(int drvslotIndex, unsigned char *pData,
									int *pnDataSize, int flag/*try to read from the saved LPDU list*/)
{
	//Read data from module
	SLPDU*			p;
	unsigned char  	regSizeL=0;
	unsigned char  	regSizeM=0;
	unsigned char  	regSta=0;
	int rc = OK;

	SM_TRACE_ENTRY(TRMOD_PHY, "PHYS_RecvData() - entry,drvslotIndex=%d,"
					"pData=0x%08X,pnDataSize=0x%08X,flag=%d\r\n",
					drvslotIndex, pData, pnDataSize, flag);

	if (PHYS_Detect(drvslotIndex) == ERR_SEACH)
	{
		SM_TRACE_ERROR(TRMOD_PHY, "PHYS_WriteReg() - card detect failed\r\n");
		return(ERR_SEACH);
	}

	if(s_hdrv_tab_slot[drvslotIndex].m_state == DRV_IDLE)
	{
		SM_TRACE_ERROR(TRMOD_PHY, "PHYS_RecvData() - slot state is idle\r\n");
		return ERR_SEACH;
	}

	if (flag && s_hdrv_tab_slot[drvslotIndex].m_firstSLPDU)
	{
		// Received data while sending previous data
		SM_TRACE_INFO(TRMOD_PHY, "PHYS_RecvData() - copy from lpdu mem queue\r\n");
		memcpy(pData, s_hdrv_tab_slot[drvslotIndex].m_firstSLPDU->m_pbLPDU,
				s_hdrv_tab_slot[drvslotIndex].m_firstSLPDU->m_len);
		*pnDataSize = s_hdrv_tab_slot[drvslotIndex].m_firstSLPDU->m_len;
		SM_TRACE_BYTES(TRMOD_PHY, TRLEV_INFO, pData, *pnDataSize,
					"PHYS_RecvData() - recv data:\r\n");

		// free the received buffer into the linked list and update the head
		p = s_hdrv_tab_slot[drvslotIndex].m_firstSLPDU;
		s_hdrv_tab_slot[drvslotIndex].m_firstSLPDU = (SLPDU *)(s_hdrv_tab_slot[drvslotIndex].m_firstSLPDU->m_next);
		ITC_DynFree((unsigned char *)p);

		SM_TRACE_RETURN(TRMOD_PHY, "PHYS_RecvData() - return\r\n");
		return(OK);
	}

	rc = CamUsbReadCmd(pData, pnDataSize, 400);
	if(rc < 0)
	{
		unsigned int i = 0;
		
		SM_TRACE_ERROR(TRMOD_PHY, "PHYS_RecvData() - return error, rc = %d\r\n", rc);
		do
		{
			rc = CamUsbReadCmd(pData, pnDataSize, 400);
			if(rc < 0)
			{
				SM_TRACE_ERROR(TRMOD_PHY, "PHYS_RecvData() - return error again, rc = %d, %d times\r\n", rc, i);
				if (PHYS_Detect(drvslotIndex) == ERR_SEACH)
				{
					SM_TRACE_ERROR(TRMOD_PHY, "PHYS_RecvData() - card detect failed\r\n");
					return(ERR_SEACH);
				}
			}
			else
			{
				SM_TRACE_BYTES(TRMOD_PHY, TRLEV_ERROR, pData, *pnDataSize>50?50:*pnDataSize, "PHYS_RecvData() - rcv data:");
				SM_TRACE_ERROR(TRMOD_PHY, "PHYS_RecvData() - return OK while try %d time\r\n", i);
				break;
			}
			i++;
		}while(rc < 0 && i < 7);

		if(i >= 7)
		{
			SM_TRACE_ERROR(TRMOD_PHY, "PHYS_RecvData() - try %d\r\n", i);
			return ERR_TRAN;//1000 ms should receive data, otherwise means error
		}
	}
	//SM_TRACE_BYTES(TRMOD_PHY, TRLEV_ERROR, pData, *pnDataSize>50?50:*pnDataSize, "PHYS_RecvData() - rcv data:");
	SM_TRACE_RETURN(TRMOD_PHY, "PHYS_RecvData() - return ok\r\n");
	return(OK);	

}


static unsigned char PHYS_SendData(int drvslotIndex, unsigned char *pData, unsigned short dataSize)
{
	unsigned char	regSta=0;
	DRV_stSignal signal;
	int rc = 0;

	//Send data to module
	SM_TRACE_ENTRY(TRMOD_PHY, "PHYS_SendData() - entry,drvslotIndex=%d,pData=0x%08X,dataSize=%d\r\n",
				drvslotIndex, pData, dataSize);
	//SM_TRACE_BYTES(TRMOD_PHY, TRLEV_NOTIFY, pData, dataSize, "PHYS_SendData() - send data:");

	if (PHYS_Detect(drvslotIndex) == ERR_SEACH)
	{
		SM_TRACE_ERROR(TRMOD_PHY, "PHYS_WriteReg() - card detect failed\r\n");
		return(ERR_SEACH);
	}

	if(s_hdrv_tab_slot[drvslotIndex].m_state == DRV_IDLE)
	{
		SM_TRACE_ERROR(TRMOD_PHY, "PHYS_SendData() - state is idle\r\n");
		return ERR_SEACH;
	}

	rc = CamUsbWriteCmd(pData, dataSize, 400);
	if(rc < 0)
	{
		unsigned int i = 0;
		SM_TRACE_ERROR(TRMOD_PHY, "PHYS_SendData() - return error, rc = %d\r\n", rc);
		do
		{
			rc = CamUsbWriteCmd(pData, dataSize, 400);
			if(rc < 0)
			{
				SM_TRACE_ERROR(TRMOD_PHY, "PHYS_SendData() - return error again, rc = %d, %d times\r\n", rc, i);
				if (PHYS_Detect(drvslotIndex) == ERR_SEACH)
				{
					SM_TRACE_ERROR(TRMOD_PHY, "PHYS_SendData() - card detect failed\r\n");
					return(ERR_SEACH);
				}
			}
			else
			{
				SM_TRACE_BYTES(TRMOD_PHY, TRLEV_ERROR, pData, dataSize>50?50:dataSize, "PHYS_SendData() - send data:");
				SM_TRACE_ERROR(TRMOD_PHY, "PHYS_SendData() - return OK while once again\r\n");
				break;
			}
			i++;
		}while(rc < 0 && i < 7);
		
		if(i >= 7)
		{
			SM_TRACE_ERROR(TRMOD_PHY, "PHYS_SendData() - try %d times, still return error\r\n", i);
			return ERR_TRAN;//1000 ms should receive data, otherwise means error
		}

	}	
//	SM_TRACE_BYTES(TRMOD_PHY, TRLEV_ERROR, pData, dataSize>50?50:dataSize, "PHYS_SendData() - send data:");
	SM_TRACE_RETURN(TRMOD_PHY, "PHYS_SendData() - return ok\r\n");
	return(OK);
}


static unsigned char PHYS_WaitCardReady(int drvslotIndex)
{
	//check the Card Detect Signal and wait for complete module initialization
	int 			count;
	DRV_stSignal 	signal = {0};
	int 			rc;

	SM_TRACE_ENTRY(TRMOD_PHY, "PHYS_WaitCardReady() - entry, drvslotIndex=%d\r\n", drvslotIndex);

	if (PHYS_Detect(drvslotIndex) != OK)
	{
		SM_TRACE_ERROR(TRMOD_PHY, "PHYS_WaitCardReady() - card detect failed,drvslotIndex=%d\r\n",drvslotIndex);
		return ERR_SEACH;
	}
	SM_TRACE_INFO(TRMOD_PHY, "PHYS_WaitCardReady() - [t%lu]card is ready\r\n", SM_GetTickCount());

	SM_Sleep(50);
	SM_TRACE_RETURN(TRMOD_PHY, "PHYS_WaitCardReady() - [t%lu]return ok, ready_sig=%d\r\n", SM_GetTickCount(),signal.value);
	return OK;
}


static unsigned char PHYS_Negociate(int drvslotIndex, unsigned int selfSize,
										unsigned short* pNegoSize)
{
	//perform buffer negociation
	unsigned char		regSta=0;
	unsigned char		buff[4];
	int 				Size;
	int 				count;
	DRV_ssSignal 		signal;
	int 				rc;

	SM_TRACE_ENTRY(TRMOD_PHY, "PHYS_Negociate() - [t%lu]entry, drvslotIndex=%d,selfSize=%d,pNegoSize=0x%08X\r\n",
					SM_GetTickCount(), drvslotIndex, selfSize, pNegoSize);

	// send buffer size to CAM
	buff[0] = 0xfe;
	buff[1] = 0;
	buff[2] = (selfSize >> 8)&0xff;
	buff[3] = selfSize&0xff;
	
	// send the buffer size to the module
	SM_TRACE_INFO(TRMOD_PHY, "PHYS_Negociate() - [t%lu]write negociation size=%d\r\n", SM_GetTickCount(),selfSize);
	count=0;
	do
	{
		rc=PHYS_SendData(drvslotIndex, buff, 4);
		if (rc == OK)
		{
			SM_TRACE_INFO(TRMOD_PHY, "PHYS_Negociate() - [t%lu]write negociation size=%d ok\r\n", SM_GetTickCount(),*pNegoSize);
			//ITC_SendXpck(g_pipePhy, XPCK_LPDU, DIRECTION_H2M, buff, 2);
			break;
		}

		if (rc != ERR_AGAIN)
		{
			SM_TRACE_INFO(TRMOD_PHY, "PHYS_Negociate() - write negociation size failed,rc=0x%02X\r\n", rc);
			return ERR_TRAN;
		}

		count++;
		if(count==PHYS_TIMEOUT)
		{
			SM_TRACE_INFO(TRMOD_PHY, "PHYS_Negociate() - [t%lu]write negociation size timeout(%d ms)\r\n", SM_GetTickCount(),count);
			return ERR_TRAN;
		}
		ITC_Sleep(PHYS_DELAY);
	} while(1);	

	SM_TRACE_INFO(TRMOD_PHY, "PHYS_Negociate() - [t%lu]wait module inform buffer size\r\n",SM_GetTickCount());
	count=0;
	do
	{
		Size = 4;
		rc=PHYS_RecvData(drvslotIndex, buff, &Size, 1);
		if (rc == OK)
		{
			SM_TRACE_INFO(TRMOD_PHY, "PHYS_Negociate() - [t%lu]wait module inform buffer size ok\r\n",SM_GetTickCount());
			//ITC_SendXpck(g_pipePhy, XPCK_LPDU, DIRECTION_M2H, buff, 2);
			break;
		}

		if (rc != ERR_AGAIN)
		{
			SM_TRACE_ERROR(TRMOD_PHY, "PHYS_Negociate() - read data failed,rc=0x%02X\r\n",rc);
			return rc;
		}

		count++;
		if(count==PHYS_TIMEOUT)
		{
			SM_TRACE_ERROR(TRMOD_PHY, "PHYS_Negociate() - [t%lu]read data timeout\r\n", SM_GetTickCount());
			return ERR_TRAN;
		}
		SM_TRACE_INFO(TRMOD_PHY, "PHYS_Negociate() - wait DA, retry count=%d, sleep %d ms ...\r\n", count, PHYS_DELAY);
		ITC_Sleep(PHYS_DELAY);
	} while(1);

	(*pNegoSize)=buff[2]*256+buff[3];
	if (*pNegoSize <= 8)
	{
		SM_TRACE_INFO(TRMOD_PHY, "PHYS_Negociate() - invalid buffer size=%d\r\n", *pNegoSize);
		return ERR_TRAN;
	}
	
	SM_TRACE_CRITICAL(TRMOD_PHY, "PHYS_Negociate() - [t%lu]module inform buffer size=%d\r\n", SM_GetTickCount(),*pNegoSize); //ytdiao

	if((*pNegoSize)>selfSize)
	{
		SM_TRACE_INFO(TRMOD_PHY, "PHYS_Negociate() - module inform buffer too big, adjust it to %d\r\n", selfSize);
		buff[0]=selfSize>>8;
		buff[1]=selfSize;
		(*pNegoSize)=selfSize;
	}

	SM_TRACE_RETURN(TRMOD_PHY, "PHYS_Negociate() - [t%lu]return ok\r\n",SM_GetTickCount());
	return OK;
}

static unsigned char PHYS_InitModule(int drvslotIndex, unsigned int selfSize,
									unsigned short* pNegoSize)
{
	//Make Initialisation of I/O window
//	unsigned int 	i;
	int 			rc;

	SM_TRACE_ENTRY(TRMOD_PHY, "PHYS_InitModule() - entry,drvslotIndex=%d,"
					"selfSize=%d,pNegoSize=0x%08X\r\n",
					drvslotIndex,selfSize,pNegoSize);

	s_hdrv_tab_slot[drvslotIndex].m_state = DRV_DISCONNECT;

	//s_usbId = OpenCamUsb();
	//if(s_usbId == -1)
	//{
	//	return ERR_SEACH;
	//}

	// Poll the Card Detect and wait for complete module initialization
	//SM_TRACE_INFO(TRMOD_PHY, "PHYS_InitModule() - usb id is %d, wait for card insert...\r\n", s_usbId);
	rc = PHYS_WaitCardReady(drvslotIndex);
	if (rc != OK)
	{
		SM_TRACE_ERROR(TRMOD_PHY, "PHYS_InitModule() - card insert failed,drvslotIndex=%d\r\n", drvslotIndex);
		s_hdrv_tab_slot[drvslotIndex].m_state = DRV_IDLE;
		return rc; // no card detect
	}

	SM_TRACE_INFO(TRMOD_PHY, "PHYS_InitModule() - the module %d is inserted\r\n",
				s_hdrv_tab_slot[drvslotIndex].m_slotId);
/*
	SM_TRACE_INFO(TRMOD_PHY, "PHYS_InitModule() - Read and Check CIS\r\n");
	rc = PHYS_ReadCIS(drvslotIndex);
	if (rc != OK)
	{
		SM_TRACE_INFO(TRMOD_PHY, "PHYS_InitModule() - Read and Check CIS failed, rc=0x%02X\r\n", rc);
		return rc;
	}
*/
	SM_TRACE_INFO(TRMOD_PHY, "PHYS_InitModule() - begin buffer negociation...\r\n");
	if(PHYS_Negociate(drvslotIndex, selfSize, pNegoSize))
	{
		SM_TRACE_ERROR(TRMOD_PHY, "PHYS_InitModule() - the module %d can't be initialized\r\n", s_hdrv_tab_slot[drvslotIndex].m_slotId);
		s_hdrv_tab_slot[drvslotIndex].m_state = DRV_IDLE;
		return(ERR_SEACH);
	}
	SM_TRACE_CRITICAL(TRMOD_PHY, "PHYS_InitModule() - [t%lu]buffer size=%d\r\n", SM_GetTickCount(),*pNegoSize); //ytdiao

	SM_TRACE_INFO(TRMOD_PHY, "PHYS_InitModule() - the module %d is initialized\r\n", s_hdrv_tab_slot[drvslotIndex].m_slotId);
	return(OK);
}


int PHYS_DRVOpen(void)
{
	//Description: open the PHYSICAL Driver
	//	- Initialize slot management table;
	//	- Open the low level PHYSICAL Driver
	// RETURN CODE
	//		> 0 : OK (number of initialized slots
	//		 -1 : error
	int 	i;
	char 	szDeviceName[32];

	SM_TRACE_ENTRY(TRMOD_PHY, "PHYS_DRVOpen() - entry\r\n");

	// Allocate intermediate buffer for read/send collision
	s_drv_databuf = ITC_DynAlloc(MAX_LPDU_SIZE);
	if (s_drv_databuf == NULL)
	{
		SM_TRACE_ERROR(TRMOD_PHY, "PHYS_DRVOpen() - alloc mem(%d) failed\r\n", MAX_LPDU_SIZE);
		return -1;
	}

	for (i=0; i < MAXSLOTID; i++)
	{
		// Initialize the slot table
		s_hdrv_tab_slot[i].m_state      = DRV_IDLE;
		s_hdrv_tab_slot[i].m_firstSLPDU = NULL;

		// Open the low level PHYSICAL Driver
		sprintf(szDeviceName, "dvbci_slot%d", i+1 );
		s_hdrv_tab_slot[i].m_slotId = 1; // ytdiao
		if (s_hdrv_tab_slot[i].m_slotId <= 0)
		{
			SM_TRACE_ERROR(TRMOD_PHY, "PHYS_DRVOpen() - Open PHYSICAL low level driver for %s failed.\r\n", szDeviceName);
			return -1;
		}

		SM_TRACE_INFO(TRMOD_PHY, "PHYS_DRVOpen() - Open PHYSICAL low level driver for %d(%s) slot success.\r\n", s_hdrv_tab_slot[i].m_slotId,szDeviceName);
	}

	s_drvNextIndex = 0;

	SM_CreateSem(&s_semPhy, "sm_phy", 1);

	CamUsbStatusChanged(PHYS_CamDetectCallback);

	SM_TRACE_RETURN(TRMOD_PHY, "PHYS_DRVOpen() - return\r\n");
	return MAXSLOTID;
}


int PHYS_DRVWrite(unsigned short slotId, unsigned char *pbLpdu, unsigned short lpduSize)
{
	//Send a LPDU to the PHYSICAL Driver
	unsigned char	rc;
	int				drvslotIndex;
	int				count;

	SM_TRACE_ENTRY(TRMOD_PHY, "PHYS_DRVWrite() - entry,slotId=%d,pbLpdu=0x%08X,lpduSize=%d\r\n",
					slotId,pbLpdu,lpduSize);

	for (drvslotIndex=0; drvslotIndex < MAXSLOTID; drvslotIndex++)
	{
		if (s_hdrv_tab_slot[drvslotIndex].m_slotId == slotId)
		{
			SM_TRACE_INFO(TRMOD_PHY, "PHYS_DRVWrite() - slot %d found, drvslotIndex=%d\r\n", slotId, drvslotIndex);
			break;
		}
	}

	if (drvslotIndex >= MAXSLOTID)
	{
		SM_TRACE_ERROR(TRMOD_PHY, "PHYS_DRVWrite() - slot %d not exits\r\n", slotId);
		return -1;			// slotId not found
	}
		
	SM_TRACE_BYTES(TRMOD_PHY, TRLEV_INFO, pbLpdu, lpduSize, "PHYS_DRVWrite() - send data:");
	count = 0;
	do
	{
		rc= PHYS_SendData(drvslotIndex, pbLpdu, lpduSize);
		if (rc == OK)
			break;

		if (rc != ERR_AGAIN)
		{
			SM_TRACE_RETURN(TRMOD_PHY, "PHYS_DRVWrite() - return failed\r\n");
			return rc;
		}

		count++;
		if(count==PHYS_TIMEOUT)
		{
			SM_TRACE_ERROR(TRMOD_PHY, "PHYS_DRVWrite() - send data timeout(%d ms)\r\n", count);
			return ERR_SEACH;	// not sent
		}
		SM_TRACE_ERROR(TRMOD_PHY, "PHYS_DRVWrite() - CAM busy, curtick=%ld, try %d,sleep %d ms...\r\n",
					SM_GetTickCount(),count,PHYS_DELAY);
		ITC_Sleep(PHYS_DELAY);
	}while(1);

	//ITC_SendXpck(g_pipePhy, XPCK_LPDU, DIRECTION_H2M, pbLpdu, lpduSize);

	SM_TRACE_RETURN(TRMOD_PHY, "PHYS_DRVWrite() - return ok\r\n");
	return OK;
}


BOOL PHYS_DRVRead(xmsg_t* pXmsg)
{
	//Read a message from the PHYSICAL Driver
	int				rc;
	int				drvslotIndex;
	int				pollCount;
	int	rcvLen;

	SM_TRACE_ENTRY(TRMOD_PHY, "PHYS_DRVRead() - entry, pXmsg=0x%08X\r\n", pXmsg);

	drvslotIndex = s_drvNextIndex;
	pollCount = 0;
	pXmsg->m_type = 0;
	
	do
	{
		pXmsg->m_type = 0;
		SM_TRACE_INFO(TRMOD_PHY, "PHYS_DRVRead() - try drv_slot_index %d\r\n", drvslotIndex);

		if (s_hdrv_tab_slot[drvslotIndex].m_state == DRV_CONNECT)
		{
			// wait for received data from inserted Module or wait for Module Extraction
			rcvLen = s_hdrv_tab_slot[drvslotIndex].m_negoSize;
			rc = PHYS_RecvData(drvslotIndex, pXmsg->m_bd.m_ph_data.m_pbData, &rcvLen, 1);

			switch (rc)
			{
			case OK :
				SM_TRACE_INFO(TRMOD_PHY, "PHYS_DRVRead() - is receive data OK\r\n");
				pXmsg->m_type = PH_DATA;
				pXmsg->m_bd.m_ph_data.m_slotId = s_hdrv_tab_slot[drvslotIndex].m_slotId;
				pXmsg->m_bd.m_ph_data.m_len    = rcvLen;
				SM_TRACE_BYTES(TRMOD_PHY, TRLEV_INFO,
								pXmsg->m_bd.m_ph_data.m_pbData, rcvLen,
								"PHYS_DRVRead() - recv data[slotId=%d]:",
								s_hdrv_tab_slot[drvslotIndex].m_slotId);

				//ITC_SendXpck(g_pipePhy, XPCK_LPDU, DIRECTION_M2H, pXmsg->m_bd.m_ph_data.m_pbData, rcvLen);
				break;

			case ERR_TRAN :
				SM_TRACE_INFO(TRMOD_PHY, "PHYS_DRVRead() - is receive data ERR_TRAN\r\n");
				pXmsg->m_type = PH_ERROR;
				pXmsg->m_bd.m_ph_error.m_slotId = s_hdrv_tab_slot[drvslotIndex].m_slotId;
				pXmsg->m_bd.m_ph_error.m_status  = LN_PHYSICAL;
				break;

			case ERR_SEACH :
				SM_TRACE_INFO(TRMOD_PHY, "PHYS_DRVRead() - is receive data ERR_SEACH\r\n");
				s_hdrv_tab_slot[drvslotIndex].m_state = DRV_DISCONNECT; //Set new state
				pXmsg->m_type = PH_EXTRACT;
				pXmsg->m_bd.m_ph_extract.m_slotId = s_hdrv_tab_slot[drvslotIndex].m_slotId;
				break;

			case ERR_AGAIN: // no complete data received
				break;

			default :
				// no complete data received
				SM_TRACE_INFO(TRMOD_PHY, "PHYS_DRVRead() - is receive data UNKOWN error\r\n");
				break;
			} //end switch
		}
		else //is disconnect
		{
			// wait for Module Insertion and Initialization
			rc = PHYS_InitModule(drvslotIndex, MAX_LPDU_SIZE,
								&s_hdrv_tab_slot[drvslotIndex].m_negoSize);
			switch (rc)
			{
			case OK :
				SM_TRACE_INFO(TRMOD_PHY, "PHYS_DRVRead() - initModule OK\r\n");
				pXmsg->m_type = PH_INSERT;
				pXmsg->m_bd.m_ph_insert.m_slotId = s_hdrv_tab_slot[drvslotIndex].m_slotId;
				pXmsg->m_bd.m_ph_insert.m_status  = LN_OK;
				pXmsg->m_bd.m_ph_insert.m_negoSize = s_hdrv_tab_slot[drvslotIndex].m_negoSize;
				s_hdrv_tab_slot[drvslotIndex].m_state = DRV_CONNECT; //Set new state
				break;

			case ERR_CIS :
				SM_TRACE_INFO(TRMOD_PHY, "PHYS_DRVRead() - wrong CIS\r\n");
				pXmsg->m_type = PH_INSERT;
				pXmsg->m_bd.m_ph_insert.m_slotId = s_hdrv_tab_slot[drvslotIndex].m_slotId;
				pXmsg->m_bd.m_ph_insert.m_status  = LN_PHYSICAL;		// wrong CIS
				pXmsg->m_bd.m_ph_insert.m_negoSize = s_hdrv_tab_slot[drvslotIndex].m_negoSize;
				s_hdrv_tab_slot[drvslotIndex].m_state = DRV_CONNECT; //Set new state
				break;

			default :
				SM_TRACE_INFO(TRMOD_PHY, "PHYS_DRVRead() - initModule error,rc=%d\r\n", rc);
				break;
			} //end switch
		}
		if (pXmsg->m_type == 0)  //no received any data
		{
			pollCount++;
			drvslotIndex++;				// try the next index if nothing receveid
			if (drvslotIndex == MAXSLOTID)
				drvslotIndex = 0;
		}
		if(rc != OK)
			ITC_Sleep(PHYS_DELAY);
	} while((pXmsg->m_type == 0) && (pollCount < MAXSLOTID));

	s_drvNextIndex++;	// index of the next PHYS_DRVRead
	if (s_drvNextIndex == MAXSLOTID)
		s_drvNextIndex = 0;

	SM_TRACE_RETURN(TRMOD_PHY, "PHYS_DRVRead() - return true\r\n");
	return TRUE;
}


int PHYS_DRVClose(void)
{
	int i;
	unsigned char *p;
	unsigned char *free_p;

	SM_TRACE_ENTRY(TRMOD_PHY, "PHYS_DRVClose() - entry\r\n");

	if (s_drv_databuf)
	{
		ITC_DynFree(s_drv_databuf);
		s_drv_databuf = NULL;
	}

	for(i=0; i < MAXSLOTID; i++)
	{
		// Close the low level PHYSICAL Driver for a slot
		if (s_hdrv_tab_slot[i].m_slotId > 0)
		{
			SM_TRACE_INFO(TRMOD_PHY, "PHYS_DRVClose() - close slot id=%d\r\n", s_hdrv_tab_slot[i].m_slotId);
			//DRV_Close(s_hdrv_tab_slot[i].m_slotId);
			s_hdrv_tab_slot[i].m_slotId = 0;
		}

		if (s_hdrv_tab_slot[i].m_firstSLPDU)
		{
			SM_TRACE_INFO(TRMOD_PHY, "PHYS_DRVClose() - free link lpdu list for slotIndex=%d\r\n", i);
			// free the linked list
			p = (unsigned char *)s_hdrv_tab_slot[i].m_firstSLPDU;
			while (((SLPDU*)p)->m_next)
			{
				free_p = p;
				p = ((SLPDU*)p)->m_next;
				ITC_DynFree(free_p);
			}
			ITC_DynFree(p);
		}
	}

	SM_TRACE_RETURN(TRMOD_PHY, "PHYS_DRVClose() - return\r\n");
	return 0;
}

